package com.gmall.product.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {

    /**
     * JoinPoint  切入点 = 方法
     * PointCut ：方法的集合
     */
    @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    public void deletePointCut(){

    }

    /**
     * 返回通知
     * 如果参数中的第一个参数为JoinPoint，则第二个参数为返回值的信息
     * 如果参数中的第一个参数不为JoinPoint，则第一个参数为returning中对应的参数
     * returning 只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知，否则不执行
     * @param joinPoint
     * @param keys
     */
    @AfterReturning(value = "deletePointCut()", returning = "keys")
    public void afterReturningAdvice(JoinPoint joinPoint, Object keys){
        System.out.println("记录日志：" +
                "方法名：" + joinPoint.getSignature().getName()
                + " 返回值："+ keys);
    }

    /**
     * 异常通知
     * 定义一个名字，该名字用于匹配通知实现方法的一个参数名，
     * 当目标方法抛出异常返回后，将把目标方法抛出的异常传给通知方法；
     * throwing 只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知，否则不执行，
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value = "execution(public * com.gmall.product.*.*(..))", throwing = "e")
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception e){
        System.out.println("AfterThrowing:----------- 异常通知 -----------");
        e.printStackTrace();
    }

}
